#pragma once
#include <iostream>
#include <string>
#include "Initadd.h"

#include "Socket.h"
#include "Connection.h"
#include "Epoll.h"
#include "Reactor.h"
#include "IOservice.h"
#include "Calculator.h"
using namespace sockedmodule;

class Listener : public Connection
{
public:
    Listener(int port) : _listensock(std::make_unique<sockedmodule::TcpSocket>()), _port(port)
    {
        _listensock->BuildTcpSocketMethod(_port);
        Setsocket(_listensock->Fd());
        SetEvent(EPOLLIN | EPOLLET);
    }

    virtual void Sender() override
    {
    }
    virtual void Recver() override
    {
        while (true)
        {
            IntAddr peer;
            int aerrno = 0;
            // accept 非阻塞的时候，就是IO，我们就向处理read一样，处理accept
            int sockfd = _listensock->Accepter(&peer, &aerrno);
            if (sockfd > 0)
            {
                // success
                // 我们毫不意外的是不能直接读取的！
                // sockfd 添加到epoll！
                // epollserver只认connection
                LOG(LogLevel::DEBUG) << "Accepter success: " << sockfd;
                // 普通的文件描述符，处理IO的，也是connection！
                // 2. sockfd包装成为Connection！
                auto conn = std::make_shared<IOservice>(sockfd);
                conn->RegisterOnMessage(HandlerRequest); //???
                //  3. 插入到EpollServer
                Getowner()->InsertConnection(conn);
            }
            else
            {
                if (aerrno == EAGAIN || aerrno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "accetper all connection ... done";
                    break;
                }
                else if (aerrno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "accetper intr by signal, continue";
                    continue;
                }
                else
                {
                    LOG(LogLevel::WARNING) << "accetper error ... Ignore";
                    break;
                }
            }
        }
    }
    virtual void Excepter() override
    {
    }
    int Sockfd()
    {
        return _listensock->Fd();
    }
    ~Listener()
    {
    }

private:
    std::unique_ptr<sockedmodule::Socket> _listensock;
    int _port;
};
